package com.example.commons.aspect;

import com.example.commons.annotation.DebounceLock;
import com.example.commons.redis.RedisLock;
import com.example.commons.util.RedisUtils;
import com.example.commons.util.RequestKeyGenerator;
import com.example.commons.util.UserUtil;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
@Order(1)
public class RedisDebounceLockAspect {


 private RedissonClient redissonClient;

    @Autowired
    RedisTemplate redisTemplate;



    @Autowired
    RedisLock redisLock;


    public RedisDebounceLockAspect(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    @Around("@annotation(com.example.commons.annotation.DebounceLock)")
    public Object debounceLock(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        DebounceLock requestLock = method.getAnnotation(DebounceLock.class);
        if(StringUtils.isEmpty(requestLock.prefix())){
            throw new RuntimeException("redis key 前缀 不能为空");

        }
        //获取自定义key
        String lockKey = RequestKeyGenerator.getLockKey(joinPoint);
        lockKey=lockKey+ UserUtil.get().getId();
        //使用redisson分布式锁的方式来判断是否重复提交
       // RLock lock = redissonClient.getLock(lockKey);
        //boolean isLocked = false;
       boolean isLocked =  RedisUtils.LockOps.getLock(lockKey,"123456",requestLock.expire(),requestLock.unit());
         try {
               //lock.tryLock();
             if(isLocked){
                 //拿到锁 设置过期时间
               // lock.lock(requestLock.expire(),requestLock.unit());
                 return joinPoint.proceed();
             } else {
                 throw  new RuntimeException("请求频繁,请稍后再试");
             }
         } catch (Exception e) {
             throw new RuntimeException("请求频繁,请稍后再试");
         }
//         finally {
         //    RedisUtils.LockOps.releaseLock(lockKey);
//            if(isLocked && lock.isHeldByCurrentThread()){
//               lock.unlock();
//            }
//         }

    }
}
